package com.xinchao.controller;

import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.xinchao.core.BaseController;
import com.xinchao.core.constant.BusinessConstant;
import com.xinchao.core.constant.ClientConstant;
import com.xinchao.core.constant.PageConstant;
import com.xinchao.core.constant.ResponseConstant;
import com.xinchao.core.exception.ControllerException;
import com.xinchao.core.util.HttpUtils;
import com.xinchao.core.util.SimpleExportUtil;
import com.xinchao.model.Area;
import com.xinchao.model.BreakdownImg;
import com.xinchao.model.User;
import com.xinchao.model.dto.DeviceInfoStatisticsDTO;
import com.xinchao.model.dto.UpdateDeviceDetailDTO;
import com.xinchao.model.sys.JsonResponse;
import com.xinchao.model.vo.DeviceDetailVO;
import com.xinchao.model.vo.DeviceInfoExportListVO;
import com.xinchao.model.vo.DeviceLogListVO;
import com.xinchao.model.vo.DeviceSimInfoVO;
import com.xinchao.service.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;

/**
 * @ClassName DeviceInfoController
 * @Description 终端管理
 * @Author HanQinrui
 * @Date 2018/8/7 14:11
 * @Version 1.0
 */
@Controller
@RequestMapping(value = "/deviceInfo")
public class DeviceInfoController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private BreakdownImgService breakdownImgService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private UserService userService;
    @Autowired
    private DeviceSimInfoService deviceSimInfoService;

    @Autowired
    private SimpleExportUtil SimpleExportUtil;

    /**
     * 终端管理分页列表
     * hanqr 2018-08-07
     *
     * @param machineNumber 机器码
     * @param propertyName  物业名称
     * @param deviceMac     设备mac
     * @param deviceIp      设备IP
     * @param administrator 管理人员
     * @param district      区/县
     * @param onlineStatus  在线状态（0.在线; 1.离线）
     * @param deviceStatus  设备状态:（0:可售  1:预拆除  2:维护）
     * @param request       请求
     * @param pageNum       当前页码
     * @param pageSize      每页条数
     * @param model         模型
     * @return
     */
    @RequestMapping(value = "/listByPage")
    public Object listByPage(String machineNumber, String propertyName, String deviceMac,
                             String deviceIp, String administrator, String district, Integer onlineStatus, Integer deviceStatus,String softwareVersion,String firmwareVersion,
                             HttpServletRequest request, Integer pageNum, Integer pageSize, Model model) {
        // 设置分页默认值
        pageNum = pageNum == null ? PageConstant.DEFAULT_PAGE_NUM : pageNum;
        pageSize = pageSize == null ? PageConstant.DEFAULT_PAGE_SIZE : pageSize;

        // 获取用户信息
        User loginUser = getSessionUser(request);
        if (loginUser == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }

        //回显
        model.addAttribute("machineNumber", machineNumber);
        model.addAttribute("propertyName", propertyName);
        model.addAttribute("deviceMac", deviceMac);
        model.addAttribute("deviceIp", deviceIp);
        model.addAttribute("administrator", administrator);
        model.addAttribute("district", district);
        model.addAttribute("onlineStatus", onlineStatus);
        model.addAttribute("deviceStatus", deviceStatus);
        model.addAttribute("softwareVersion", softwareVersion);
        model.addAttribute("firmwareVersion", firmwareVersion);
        model.addAttribute("pageNum", pageNum);
        model.addAttribute("pageSize", pageSize);
//		model.addAttribute("total",page.getTotal());
//		model.addAttribute("onLineDeviceCount",onLineDeviceCount);
//		model.addAttribute("offLineDeviceCount",offLineDeviceCount);
        //model.addAttribute("deviceList",page.getList());
        //model.addAttribute("districtList",districtList);
        return new ModelAndView("deviceInfo_list");
    }

    /**
     * 导出终端管理列表
     * hanqr 2018-08-08
     *
     * @param machineNumber 机器码
     * @param propertyName  物业名称
     * @param deviceMac     设备mac
     * @param deviceIp      设备IP
     * @param administrator 管理人员
     * @param district      区/县
     * @param onlineStatus  在线状态（0.在线; 1.离线）
     * @param deviceStatus  设备状态:（0:可售  1:预拆除  2:维护）
     * @param response
     */
    @RequestMapping("/exportDeviceList")
    public void exportDeviceList(String machineNumber, String propertyName, String deviceMac, String deviceIp, String administrator,
                                 String district, Integer onlineStatus, Integer deviceStatus,String softwareVersion,String firmwareVersion, HttpServletResponse response, HttpServletRequest request) {
        try (OutputStream out = response.getOutputStream()) {
            // 获取用户信息
            User loginUser = getSessionUser(request);
            if (loginUser == null) {
                throw new ControllerException("用户名为空，请联系管理员");
            }
            // 当前登录城市
            String cityName = loginUser.getCityName();
            List<DeviceInfoExportListVO> exportList = Lists.newArrayList();
            exportList = deviceInfoService.listExportDevice(cityName, machineNumber, propertyName, deviceMac, deviceIp, administrator, district, onlineStatus, deviceStatus, softwareVersion,firmwareVersion);

            //设置输出类型
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            //设置文件名
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(("终端列表.xls").getBytes(), "ISO-8859-1"));
            SimpleExportUtil.exportToExcel(exportList, "终端列表").write(out);
        } catch (Exception e) {
            logger.error("DeviceInfoController exportDeviceList 终端列表失败：" + e.getMessage());
        }
    }

    /**
     * 终端日志分页列表
     * hanqr 2018-08-09
     *
     * @param startTime  开始时间
     * @param endTime    结束时间
     * @param deviceCode 终端唯一编码
     * @param logType    日志类型 crash:崩溃日志, run:运行日志, play:播放日志
     * @param pageNum    当前页码
     * @param pageSize   每页条数
     * @param model      模型
     * @param request
     * @return
     */
    @RequestMapping(value = "/deviceLogList")
    public Object deviceLogList(String deviceCode, String startTime, String endTime, String logType,
                                Integer pageNum, Integer pageSize, Model model, HttpServletRequest request) {
        // 获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        // 设置分页默认值
        pageNum = pageNum == null ? PageConstant.DEFAULT_PAGE_NUM : pageNum;
        pageSize = pageSize == null ? PageConstant.DEFAULT_PAGE_SIZE : pageSize;
        logType = "ALL".equals(logType) ? null : logType;
        Page<DeviceLogListVO> page = deviceInfoService.listDeviceLogs(deviceCode, startTime, endTime, logType, pageNum, pageSize);
        model.addAttribute("list", page.getResult());
        model.addAttribute("total", page.getTotal());
        model.addAttribute("pageNum", page.getPageNum());
        model.addAttribute("pageSize", page.getPageSize());
        model.addAttribute("deviceCode", deviceCode);
        model.addAttribute("startTime", startTime);
        model.addAttribute("endTime", endTime);
        model.addAttribute("logType", logType);
        return new ModelAndView("deviceLog_list");
    }

    /**
     * 获取终端管理可授权人员
     * hanqr 2018-08-09
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/getDeviceAuthorityUsersList")
    public Object getDeviceAuthorityUsersList(HttpServletRequest request) {
        // 获取当前用户和部门id
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        Long departmentId = user.getDepartmentId();
        // 通过部门id查询部门所属人员
        List<HashMap<String, String>> departmentUsersList = departmentService.getUsersByDepartmentId(departmentId);
        return departmentUsersList;
    }

    /**
     * 终端管理授权
     * hanqr 2018-08-09
     *
     * @param request
     * @param deviceCodes  终端唯一编码(多个编码之间用逗号隔开)
     * @param administrans 授权人id(多个id之间用逗号隔开)
     * @return
     */
    @ResponseBody
    @RequestMapping("/deviceAuthority")
    public Object deviceAuthority(HttpServletRequest request, String deviceCodes, String administrans) {
        // 获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes)) {
            return new ControllerException("终端信息错误，请重试");
        }
        if (StringUtils.isBlank(administrans)) {
            return new ControllerException("授权人员不可为空，请重试");
        }
        try {
            deviceInfoService.deviceAuthority(deviceCodes, administrans, user, request);
        } catch (Exception e) {
            logger.error("DeviceInfoController deviceAuthority 终端管理授权失败：" + e.getMessage());
            return new ControllerException("终端管理授权失败");
        }
        return "";
    }

    /**
     * 获取授权管理人的信息
     * hanqr 2018-08-10
     *
     * @param userId 用户Id
     * @return
     */
    @ResponseBody
    @RequestMapping("/getAuthorityUserInfo")
    public Object getAuthorityUserInfo(String userId) {
        if (StringUtils.isBlank(userId)) {
            return new ControllerException("终端管理人员错误，请重试");
        }
        User user = new User();
        List<HashMap<String, String>> resultList = Lists.newArrayList();
        try {
            user = userService.getUserById(Long.valueOf(userId));
            HashMap<String, String> map = new HashMap<>();
            if (StringUtils.isBlank(user.getMobilePhone())) {
                user.setMobilePhone("暂无");
            }
            if (StringUtils.isBlank(user.getEmail())) {
                user.setEmail("暂无");
            }
            map.put("mobilePhone", user.getMobilePhone());
            map.put("email", user.getEmail());
            resultList.add(map);
        } catch (Exception e) {
            logger.error("DeviceInfoController getAuthorityUserInfo 查询管理人信息失败：" + e.getMessage());
            return new ControllerException("查询管理人信息失败");
        }
        return resultList;
    }

    /**
     * 更新终端详情部分信息
     * linq 2018-08-09
     *
     * @param request      请求
     * @param deviceDetail 修改的终端信息对象
     * @return
     */
    @RequestMapping(value = "/detail/update")
    @ResponseBody
    public Object updateDeviceDetail(HttpServletRequest request, @RequestBody UpdateDeviceDetailDTO deviceDetail) {
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        try {
            String checkResult = checkDevice(deviceDetail);
            if (StringUtils.isNotBlank(checkResult)) {
                return new JsonResponse(ResponseConstant.CODE_FAIL, checkResult);
            }
            deviceInfoService.updateDevice(deviceDetail, request);
            return new JsonResponse(ResponseConstant.CODE_SUCCESS, checkResult);
        } catch (Exception e) {
            logger.error("DeviceInfoController updateDeviceDetail 修改终端信息失败：" + e.getMessage());
        }
        return new JsonResponse(ResponseConstant.CODE_FAIL, "修改终端信息失败");
    }

    /**
     * 跳转终端详情页面
     * 2018-08-09
     *
     * @param request 请求
     * @param model   模型
     * @return Object
     * @author linqiang
     */
    @RequestMapping(value = "/deviceDetail/{deviceId}")
    public Object deviceDetail(HttpServletRequest request, @PathVariable Long deviceId, Model model) {
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        DeviceSimInfoVO deviceSimInfoVO = null;
        DeviceDetailVO deviceDetailVO = deviceInfoService.getDeviceDetail(deviceId);
        if (null != deviceDetailVO) {
            List<BreakdownImg> breakdownImgList = breakdownImgService.list(deviceDetailVO.getDeviceCode());
            model.addAttribute("breakdownImgList", breakdownImgList);
            deviceSimInfoVO = deviceSimInfoService.selectByDeviceCode(deviceDetailVO.getDeviceCode());
            if (null == deviceSimInfoVO) {
                deviceSimInfoVO = new DeviceSimInfoVO();
            }
        } else {
            deviceDetailVO = new DeviceDetailVO();
            deviceSimInfoVO = new DeviceSimInfoVO();
        }
        model.addAttribute("deviceSimInfo", deviceSimInfoVO);
        model.addAttribute("device", deviceDetailVO);
        return new ModelAndView("device_detail");
    }

    /**
     * 远程关机指令
     * hanqr 2018-08-10
     *
     * @param deviceCodes 终端唯一编码
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/shutdown")
    public Object shutdown(String deviceCodes, HttpServletRequest request) {
        // 获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        //	deviceCodes不能为空
        if (StringUtils.isBlank(deviceCodes)) {
            return new ControllerException(ClientConstant.MSG_PARAM_ERROR);
        }
        try {
            deviceInfoService.shutdown(deviceCodes, user, HttpUtils.getRemortIP(request));
        } catch (Exception e) {
            logger.error("DeviceInfoController shutdown 关机失败：" + e.getMessage());
            return new ControllerException("关机失败");
        }
        return "";
    }

    /**
     * 重启终端
     * hanqr 2018-08-13
     *
     * @param deviceCodes 终端唯一编码
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/restart")
    public Object restart(String deviceCodes, HttpServletRequest request) {
        //获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes)) {
            return new ControllerException(ClientConstant.MSG_PARAM_ERROR);
        }
        try {
            deviceInfoService.restart(deviceCodes, user, HttpUtils.getRemortIP(request));
        } catch (Exception e) {
            logger.error("DeviceInfoController restart 重启失败：" + e.getMessage());
            return new ControllerException("重启失败");
        }
        return "";
    }

    /**
     * 设置定时开关机
     * hanqr 2018-08-13
     *
     * @param deviceCodes 终端唯一编码
     * @param bootTime    开机时间
     * @param offTime     关机时间
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/setTimerShutDownOrStart")
    public Object setTimerShutDownOrStart(String deviceCodes, String bootTime, String offTime, HttpServletRequest request) {
        // 获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes) || StringUtils.isBlank(bootTime) || StringUtils.isBlank(offTime)) {
            return new ControllerException("输入参数不能为空");
        }
        try {
            deviceInfoService.setBootAndOffTimmer(deviceCodes, user, HttpUtils.getRemortIP(request), bootTime, offTime);
            ;
        } catch (Exception e){
            logger.error("DeviceInfoController setTimerShutDownOrStart 设置定时开关机失败：" + e.getMessage());
            return new ControllerException("设置定时开关机失败");
        }
        return "";
    }


    /**
     * 设置音量
     * hanqr 2018-08-13
     *
     * @param deviceCodes  终端唯一编码
     * @param deviceVolume 音量
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/setVolume")
    public Object setVolume(String deviceCodes, Integer deviceVolume, HttpServletRequest request) {
        // 获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes) || deviceVolume == null) {
            return new ControllerException("输入参数不能为空");
        }
        try {
            deviceInfoService.setVolume(deviceCodes, user, HttpUtils.getRemortIP(request), deviceVolume);
        } catch (Exception e) {
            logger.error("DeviceInfoController setVolume 设置音量失败：" + e.getMessage());
            return new ControllerException("设置音量失败");
        }
        return "";
    }

    /**
     * 检查更新设置字段
     *
     * @param updateDeviceDetailDTO 待更新的字段对象
     * @return 参数有误返回具体原因，成功返回空字符
     */
    private String checkDevice(UpdateDeviceDetailDTO updateDeviceDetailDTO) {
        if (null == updateDeviceDetailDTO.getDeviceId()) {
            return "终端ID不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getDistrict())) {
            return "区/县不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getDetailAddress())) {
            return "详细地址不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getPropertyName())) {
            return "物业名称不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getBuildingName())) {
            return "楼栋名称不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getUnitName())) {
            return "单元名称不能为空";
        }
        if (StringUtils.isBlank(updateDeviceDetailDTO.getAdministrator())) {
            return "管理人不能为空";
        }
        if (null == updateDeviceDetailDTO.getDeviceStatus()) {
            return "设备状态不能为空";
        }
        return "";
    }

    /**
     * 设置SIM卡状态(0:启用 1:关停)
     *
     * @param deviceCodes
     * @param simStatus
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/setSimStatus")
    public Object setSimStatus(String deviceCodes, Integer simStatus, HttpServletRequest request) {
        //获取用户信息
        User loginUser = getSessionUser(request);
        if (loginUser == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes) || simStatus == null) {
            return new ControllerException("输入参数不能为空");
        }
        try {
            deviceSimInfoService.setSimStatus(deviceCodes, simStatus, loginUser, HttpUtils.getRemortIP(request));
        } catch (Exception e) {
            StringBuilder msg = new StringBuilder("");
            if (BusinessConstant.STATUS_ENABLE == simStatus) {
                msg.append("启用");
            } else if (BusinessConstant.STATUS_DISABLE == simStatus) {
                msg.append("关停");
            }
            logger.error("DeviceInfoController setSimStatus " + msg.toString() + "SIM卡失败：" + e.getMessage());
            return new ControllerException(msg.toString() + "SIM卡失败");
        }
        return "";
    }

    /**
     * 终端测速
     *
     * @param deviceCodes 终端唯一编码
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/testNetwordSpeed")
    public Object testNetworkSpeed(String deviceCodes, HttpServletRequest request) {
        //获取用户信息
        User user = getSessionUser(request);
        if (user == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }
        if (StringUtils.isBlank(deviceCodes)) {
            return new ControllerException(ClientConstant.MSG_PARAM_ERROR);
        }
        try {
            deviceInfoService.testNetworkSpeed(deviceCodes, user, HttpUtils.getRemortIP(request));
        } catch (Exception e) {
            logger.error("DeviceInfoController testNetworkSpeed 测速失败：" + e.getMessage());
            return new ControllerException("测速失败");
        }
        return "";
    }

    /**
     * 查询设备列表 纯返回数据
     *
     * @param machineNumber
     * @param propertyName
     * @param deviceMac
     * @param deviceIp
     * @param administrator
     * @param district
     * @param onlineStatus
     * @param deviceStatus
     * @param request
     * @param pageNum
     * @param pageSize
     * @return
     */
    @ResponseBody
    @RequestMapping("/listdata")
    public Object deviceListData(String machineNumber, String propertyName, String deviceMac,
                                 String deviceIp, String administrator, String district, Integer onlineStatus, Integer deviceStatus, String softwareVersion, String firmwareVersion,
                                 HttpServletRequest request, Integer pageNum, Integer pageSize) {
        // 设置分页默认值
        pageNum = pageNum == null ? PageConstant.DEFAULT_PAGE_NUM : pageNum;
        pageSize = pageSize == null ? PageConstant.DEFAULT_PAGE_SIZE : pageSize;

        // 获取用户信息
        User loginUser = getSessionUser(request);
        if (loginUser == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }

        // 查询当前登录城市所有行政区
        String cityName = loginUser.getCityName();
        // 查询终端分页列表
        return deviceInfoService.listByPage(cityName, machineNumber, propertyName, deviceMac, deviceIp,
                administrator, district, onlineStatus, deviceStatus, softwareVersion, firmwareVersion, pageNum, pageSize);

    }

    /**
     * 查询设备列表 纯返回数据
     *
     * @param machineNumber
     * @param propertyName
     * @param deviceMac
     * @param deviceIp
     * @param administrator
     * @param district
     * @param onlineStatus
     * @param deviceStatus
     * @param softwareVersion apk版本号
     * @param firmwareVersion 固件版本号
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/statistics")
    public Object deviceStatisticsData(String machineNumber, String propertyName, String deviceMac,
                                       String deviceIp, String administrator, String district, Integer onlineStatus, Integer deviceStatus, String softwareVersion, String firmwareVersion,
                                       HttpServletRequest request) {

        // 获取用户信息
        User loginUser = getSessionUser(request);
        if (loginUser == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }

        // 查询当前登录城市所有行政区
        String cityCode = loginUser.getCityCode();
        // 根据条件查询在线终端总数和离线终端总数
        Long onLineDeviceCount = 0L;
        Long offLineDeviceCount = 0L;

        onLineDeviceCount = deviceInfoService.getDeviceCountByCondition(cityCode, BusinessConstant.DEVICE_INFO_STATUS_ON_LINE, softwareVersion, firmwareVersion, null,
                machineNumber, propertyName, deviceMac, deviceIp, administrator, district, deviceStatus);
        offLineDeviceCount = deviceInfoService.getDeviceCountByCondition(cityCode, BusinessConstant.DEVICE_INFO_STATUS_OFF_LINE, softwareVersion, firmwareVersion, null,
                machineNumber, propertyName, deviceMac, deviceIp, administrator, district, deviceStatus);

        return new DeviceInfoStatisticsDTO(onLineDeviceCount, offLineDeviceCount);

    }

    /**
     * 查询员工当前能够查看的市信息
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/listDistrict")
    public Object listDistrict(HttpServletRequest request) {
        // 获取用户信息
        User loginUser = getSessionUser(request);
        if (loginUser == null) {
            return new ControllerException("用户名为空，请联系管理员");
        }

        // 查询当前登录城市所有行政区
        String cityCode = loginUser.getCityCode();
        String cityName = loginUser.getCityName();
        List<Area> districtList = deviceInfoService.getDistrictByCityCode(cityCode);
        return districtList;
    }
}
